package demoMod.invincibleOne.patches;

import basemod.ReflectionHacks;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch;
import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch;
import com.evacipated.cardcrawl.modthespire.lib.SpireReturn;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.helpers.FontHelper;
import com.megacrit.cardcrawl.helpers.ImageMaster;
import com.megacrit.cardcrawl.helpers.TipHelper;
import com.megacrit.cardcrawl.helpers.input.InputHelper;
import com.megacrit.cardcrawl.ui.panels.TopPanel;
import demoMod.invincibleOne.InvincibleOneMod;
import demoMod.invincibleOne.characters.InvincibleOne;
import demoMod.invincibleOne.skins.PrimeSkin;
import demoMod.invincibleOne.skins.Skin;

import java.lang.reflect.Method;

public class TopPanelPatch {
    public static final String[] PRIME_TEXT = CardCrawlGame.languagePack.getUIString(InvincibleOneMod.makeID("PrimeForm")).TEXT;

    @SpirePatch(
            clz = TopPanel.class,
            method = "setupAscensionMode"
    )
    public static class PatchSetupAscensionMode {
        public static SpireReturn<Void> Prefix(TopPanel topPanel) {
            if (AbstractDungeon.player instanceof InvincibleOne) {
                float floorX = ReflectionHacks.getPrivateStatic(TopPanel.class, "floorX");
                topPanel.ascensionHb.move( floorX + 100.0F * Settings.scale, Settings.HEIGHT - 32.0F * Settings.scale);
                StringBuilder sb = new StringBuilder();

                for(int i = 0; i <= InvincibleOneMod.seriousLevel[CardCrawlGame.saveSlot]; ++i) {
                    sb.append(CharacterOptionPatch.TEXT[i]);
                    if (i != InvincibleOneMod.seriousLevel[CardCrawlGame.saveSlot]) {
                        sb.append(" NL ");
                    }
                }

                ReflectionHacks.setPrivate(topPanel, TopPanel.class, "ascensionString", sb.toString());
                return SpireReturn.Return(null);
            }
            return SpireReturn.Continue();
        }
    }

    @SpirePatch(
            clz = TopPanel.class,
            method = "updateAscensionHover"
    )
    public static class PatchUpdateAscensionHover {
        @SpireInsertPatch(rloc = 1)
        public static SpireReturn<Void> Insert(TopPanel topPanel) {
            if (AbstractDungeon.player instanceof InvincibleOne) {
                if (topPanel.ascensionHb.hovered) {
                    String ascensionString = ReflectionHacks.getPrivate(topPanel, TopPanel.class, "ascensionString");
                    TipHelper.renderGenericTip((float) InputHelper.mX + 50.0F * Settings.scale, Settings.HEIGHT - 120.0F * Settings.scale, CharacterOptionPatch.TEXT[12], ascensionString);
                }
                return SpireReturn.Return(null);
            }
            return SpireReturn.Continue();
        }
    }

    @SpirePatch(
            clz = TipHelper.class,
            method = "render"
    )
    public static class RenderPrimeText {
        @SpireInsertPatch(rloc = 104 - 58)
        public static void Insert(SpriteBatch sb) {
            String str = ReflectionHacks.getPrivateStatic(TipHelper.class, "HEADER");
            if (str.equals(CharacterOptionPatch.TEXT[12]) && Skin.skinNow().isPrimeForm) {
                Method method;
                try {
                    Class<?> clazz = TipHelper.class;
                    method = clazz.getDeclaredMethod("renderTipBox", float.class, float.class, SpriteBatch.class, String.class, String.class);
                    method.setAccessible(true);
                    method.invoke(null, (float) InputHelper.mX + 50.0F * Settings.scale + 320.0F * Settings.scale, Settings.HEIGHT - 120.0F * Settings.scale,
                            sb, CharacterSelectPatch.TEXT[4], PRIME_TEXT[0]);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @SpirePatch(
            clz = TopPanel.class,
            method = "renderDungeonInfo"
    )
    public static class PatchRenderDungeonInfo {
        @SpireInsertPatch(rloc = 1638 - 1627)
        public static SpireReturn<Void> Insert(TopPanel topPanel, SpriteBatch sb) {
            if (AbstractDungeon.player instanceof InvincibleOne) {
                float floorX = ReflectionHacks.getPrivateStatic(TopPanel.class, "floorX");
                float ICON_Y = ReflectionHacks.getPrivateStatic(TopPanel.class, "ICON_Y");
                float ICON_W = ReflectionHacks.getPrivateStatic(TopPanel.class, "ICON_W");
                float INFO_TEXT_Y = ReflectionHacks.getPrivateStatic(TopPanel.class, "INFO_TEXT_Y");
                sb.draw(ImageMaster.TP_ASCENSION, floorX + 106.0F * Settings.scale, ICON_Y, ICON_W, ICON_W);
                if (Skin.skinNow().isPrimeForm) {
                    FontHelper.renderFontLeftTopAligned(sb, FontHelper.topPanelInfoFont, "PRIME",
                            floorX + 166.0F * Settings.scale, INFO_TEXT_Y, Settings.GOLD_COLOR);
                }
                else if (InvincibleOneMod.seriousLevel[CardCrawlGame.saveSlot] == 10) {
                    FontHelper.renderFontLeftTopAligned(sb, FontHelper.topPanelInfoFont, String.format("%d%%", InvincibleOneMod.seriousLevel[CardCrawlGame.saveSlot] * 10), floorX + 166.0F * Settings.scale, INFO_TEXT_Y, Settings.GOLD_COLOR);
                } else {
                    FontHelper.renderFontLeftTopAligned(sb, FontHelper.topPanelInfoFont, String.format("%d%%", InvincibleOneMod.seriousLevel[CardCrawlGame.saveSlot] * 10), floorX + 166.0F * Settings.scale, INFO_TEXT_Y, Settings.RED_TEXT_COLOR);
                }
                if (topPanel.ascensionHb != null)
                    topPanel.ascensionHb.render(sb);
                return SpireReturn.Return();
            }
            return SpireReturn.Continue();
        }
    }
}
